home *** CD-ROM | disk | FTP | other *** search
- /* graphics:
- gxFont menu library routines
- by Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good, Robert Johnson, Keith McGreggor, Mike Reed, Oliver Steele, David Van Brink, Chris Yerga
- Copyright ©1987 - 1991 Apple Computer, Inc. All rights reserved.
- */
-
- #include <Resources.h>
- #include <Menus.h>
- #include <Memory.h>
- #include <ToolUtils.h>
- #include <Types.h>
- #include <Fonts.h>
-
- #include "graphics types.h"
- #include "font menu library.h"
- #include "font routines.h"
- #include "font library.h"
- #include "graphics routines.h"
- #include "layout routines.h"
- #if !defined(__powerc)
- pascal Handle XGetNextFOND(Handle fontHandle) = {0x700A, 0xA822}; /* this disappeared in the latest release of THINK C */
- #else
- #define XGetNextFOND GetNextFOND
- #endif
-
- #ifdef MacintoshIncludes
- #endif
-
-
- /*****************************************
- * Menu manager library routines to handle fonts *
- *****************************************/
-
- static long AppendMenuName(MenuHandle menu, long length, unsigned char name[])
- {
- name[0] = length < 255 ? length : 255;
- AppendMenu(menu, (const unsigned char *) "\pfont name"); /*** some full names disable the item */ /* cast for Think C 4.0 */
- #if !defined(__powerc) && !defined(ppcinterfaces)
- SetItem(menu, CountMItems(menu), name);
- #else
- SetMenuItemText(menu, CountMItems(menu), name);
- #endif
- return length > 255;
- }
-
- static MenuHandle NewMenuName(short menuID, long length, unsigned char *title)
- {
- Str255 str;
-
- str[0] = length < 255 ? length : 255;
- BlockMove(title+1, &str[1], str[0]);
- return NewMenu(menuID, str);
- }
-
- static int Str255Compare(Str255 a, Str255 b)
- {
- int i, minSize = a[0] < b[0] ? a[0] : b[0];
-
- for (i = 1; i < minSize; i++) {
- if (a[i] == b[i])
- continue;
- return a[i] - b[i];
- }
- return a[0] - b[0];
- }
-
- /*
- * sorts the text, command char, and item mark
- * this way any submenus will sort with the item
- * THIS SHOULD CALL SOME COOL INTL. SORT ROUTINE
- */
- void SortMenu(MenuHandle menu)
- {
- short i, j, count = CountMItems(menu);
-
- for (i = 2; i <= count; i++)
- for (j = count; j >= i; --j) {
- short lowercmdChar, uppercmdChar;
- short lowermarkChar, uppermarkChar;
- Str255 lower, upper;
- #if !defined(__powerc) && !defined(ppcinterfaces)
- GetItem(menu, j, lower);
- GetItem(menu, j-1, upper);
- #else
- GetMenuItemText(menu, j, lower);
- GetMenuItemText(menu, j-1, upper);
- #endif
- GetItemCmd ( menu, j, &lowercmdChar );
- GetItemCmd ( menu, j-1, &uppercmdChar );
- GetItemMark ( menu, j, &lowermarkChar );
- GetItemMark ( menu, j-1, &uppermarkChar );
-
- if (Str255Compare(lower, upper) < 0) {
- #if !defined(__powerc) && !defined(ppcinterfaces)
- SetItem(menu, j, upper);
- SetItem(menu, j-1, lower);
- #else
- SetMenuItemText(menu, j, upper);
- SetMenuItemText(menu, j-1, lower);
- #endif
- SetItemCmd ( menu, j, uppercmdChar );
- SetItemCmd ( menu, j-1, lowercmdChar );
- SetItemMark ( menu, j, uppermarkChar );
- SetItemMark ( menu, j-1, lowermarkChar );
- }
- }
- }
-
- /*
- * Append a menu with the fonts' full names
- */
- long FontMenu(MenuHandle menu)
- {
- return FontPlatformMenu(menu, gxNoPlatform, gxNoScript, gxNoLanguage);
- }
-
- /*
- * Append a menu with the fonts' full names for fonts that support the specified platform
- */
- long FontPlatformMenu(MenuHandle menu, gxFontPlatform platform, gxFontScript script, gxFontLanguage language)
- {
- gxFont* fonts;
- long i, count, nameIndex;
-
- count = GXFindFonts(nil, 0, platform, script, language, 0, nil, 1, gxSelectToEnd, 0);
- fonts = (gxFont*)NewPtr(count * sizeof(gxFont));
- GXFindFonts(nil, 0, platform, script, language, 0, nil, 1, count, fonts);
-
- for (i = 0; i < count; i++)
- { unsigned char *name;
- long length;
-
- if ((length = GXFindFontName(fonts[i], gxFullFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, nil, &nameIndex)) > 0) {
- name = (unsigned char *) NewPtr(length + 1);
- GXGetFontName(fonts[i], nameIndex, nil, nil, nil, nil, &name[1]);
- AppendMenuName(menu, length, name);
- DisposePtr((Ptr) name);
- }
- }
- DisposePtr((Ptr)fonts);
- SortMenu(menu);
- return count;
- }
-
- /*
- * Append a menu with the fonts' family names
- */
- long FontFamilyMenu(MenuHandle menu)
- {
- return FontFamilyPlatformMenu(menu, gxNoPlatform, gxNoScript, gxNoLanguage);
- }
-
- long FontFamilyPlatformMenu(MenuHandle menu, gxFontPlatform platform, gxFontScript script, gxFontLanguage language)
- {
- gxFont* fonts;
- long i, count;
-
- count = GXFindFonts(nil, gxFamilyFontName, platform, script, language, 0, nil, 1, gxSelectToEnd, nil);
- fonts = (gxFont*)NewPtr(count * sizeof(gxFont));
- GXFindFonts(nil, gxFamilyFontName, platform, script, language, 0, nil, 1, count, fonts);
-
- for (i = 0; i < count; i++)
- { unsigned char name[256];
-
- name[0] = GXFindFontName(fonts[i], gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, &name[1], nil);
- if (name[0])
- AppendMenuName(menu, name[0], name);
- }
- DisposePtr((Ptr)fonts);
- SortMenu(menu);
- return count;
- }
-
- /*
- * Create a menu with the given gxFont family's name, filled with the styles available in that family
- */
- MenuHandle FontStyleMenu(short menuID, gxFont family)
- {
- long i, count = CountFontStyles(family);
- long length;
- MenuHandle menu;
- unsigned char *name;
-
- if ((length = GXFindFontName(family, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, nil, nil)) > 0) {
- name = (unsigned char *) NewPtr(length + 1);
- GXFindFontName(family, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, &name[1], nil);
- menu = NewMenuName(menuID, length, name);
- DisposePtr((Ptr) name);
- } else
- menu = NewMenu(menuID, (unsigned char *) "\pNo family name"); /* cast for Think C 4.0 */
-
- for (i = 1; i <= count; i++) {
- gxFont sfnt = FindFontStyle(family, i, 0, 0, 0, 0, nil);
- if ((length = GXFindFontName(sfnt, gxStyleFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, nil, nil)) > 0) {
- name = (unsigned char *) NewPtr(length + 1);
- GXFindFontName(sfnt, gxStyleFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, &name[1], nil);
- AppendMenuName(menu, length, name);
- DisposePtr((Ptr)name);
- }
- }
- SortMenu(menu);
-
- return menu;
- }
-
- /*********************************************/
- /* HierFontMenu */
- /* */
- /* the firstHierMenuID let's the application decide */
- /* what number the heir menu IDs start */
- /* */
- /*********************************************/
- short HierFontMenu(MenuHandle theMenu, short firstHierMenuID, fontFilterProc proc, fontMenuAttribute attr)
- {
- long i, count;
- short heirsUsed = 0;
- long howManyInstances;
- long howManyVariations;
- gxFontVariation *variations;
- gxFontName fontNameID;
-
- count = GXFindFonts(nil, 0, 0, 0, 0, 0, nil, 1, gxSelectToEnd, 0);
- for (i = 1; i <= count; i++)
- { gxFont fontID;
- long length;
-
- GXFindFonts(nil, 0, 0, 0, 0, 0, nil, i, 1, &fontID);
- if (proc && !proc(fontID))
- continue;
- length = GXFindFontName(fontID, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, nil, nil);
- if (length)
- {
- unsigned char *name;
- Boolean alreadyInMenu = false;
- short numMItem;
- short k;
-
- name = (unsigned char *) NewPtr(length + 1);
- GXFindFontName(fontID, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, &name[1], nil);
- numMItem = CountMItems(theMenu);/*how many items have i already added to the menu*/
- for (k=1; k<= numMItem; k++) /*check to see if the name is already in the menu*/
- {
- Str255 str;
- #if !defined(__powerc) && !defined(ppcinterfaces)
- GetItem (theMenu, k, str);
- #else
- GetMenuItemText (theMenu, k, str);
- #endif
- name[0] = length; /*fake str255*/
- if ( !Str255Compare(str, name) )
- alreadyInMenu = true;
- }
- if (!alreadyInMenu) /*if not then add it*/
- {
- MenuHandle hMenu;
-
- AppendMenuName(theMenu, length, name);
- hMenu = FontStyleMenu(heirsUsed + firstHierMenuID, fontID);
- howManyInstances = (attr & noInstancesFontMenu) ? 0 : GXCountFontInstances(fontID);
- if( ( (CountMItems(hMenu)) > 1) || (howManyInstances > 0) )/*only add it if it is more than one item*/
- {
- InsertMenu (hMenu, -1);
-
- SetItemCmd(theMenu, numMItem+1, hMenuCmd);
- SetItemMark(theMenu, numMItem+1, heirsUsed + firstHierMenuID);
- heirsUsed ++;
- }
-
- if(howManyInstances)
- {
- short m;
-
- howManyVariations = GXCountFontVariations(fontID);
- variations = (gxFontVariation*)NewPtr(sizeof(gxFontVariation) * howManyVariations);
-
- AppendMenu(hMenu, (const unsigned char *) "\p(-" ); /*dotted gxLine*/
- for(m = 1; m<=howManyInstances; m++)
- {
- DisposePtr((Ptr) name);
- fontNameID = GXGetFontInstance(fontID, m, variations);
- if ((length = GXFindFontName(fontID, fontNameID, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, nil, nil)) > 0)
- {
- name = (unsigned char *) NewPtr(length+1);
- GXFindFontName(fontID, fontNameID, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, &name[1], nil);
- AppendMenuName(hMenu, length, name);
- }
- }
- }
- }
- DisposePtr((Ptr) name);
- }
- }
- SortMenu(theMenu);
- return(heirsUsed);
- }
-
-
- gxFont DoHierFontMenuCommand(long menuResult, short hierFontMenuID, long *instanceIndex)
- {
- short theItem = LoWord (menuResult);
- short theMenuID = HiWord (menuResult);
- gxFont sfnt = 0;
- Str255 str;
- Str255 regStr = "\pRegular";
-
- *instanceIndex = 0;
-
- if( theMenuID == hierFontMenuID)
- {
- #if !defined(__powerc) && !defined(ppcinterfaces)
- GetItem(GetMHandle(theMenuID), theItem, str);
- #else
- GetMenuItemText(GetMenuHandle(theMenuID), theItem, str);
- #endif
- GXFindFonts(nil, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, str[0], str+1, 1,1,&sfnt);
- GXFindFonts(sfnt, gxStyleFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, regStr[0], regStr+1, 1,1,&sfnt);
- }
- else if( theMenuID==0) /*check if the mouseup was on a family name, if so set sfnt to plain of family???*/
- {
- long mResult = MenuChoice();
- theItem = LoWord (mResult);
- theMenuID = HiWord (mResult);
- if( (theMenuID == hierFontMenuID) && (theItem!=0) )/*could be zero from some other menu*/
- {
- #if !defined(__powerc) && !defined(ppcinterfaces)
- GetItem(GetMHandle(theMenuID), theItem, str);
- #else
- GetMenuItemText(GetMenuHandle(theMenuID), theItem, str);
- #endif
- GXFindFonts(nil, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, str[0], str+1, 1,1,&sfnt);
- GXFindFonts(sfnt, gxStyleFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, regStr[0], regStr+1, 1,1,&sfnt);
- }
- }
- /* else if( (theMenuID>0) && (theMenuID<235) && (*( (short*)(0x00000a26) ) == hierFontMenuID) ) // range of hierarchial submenus && owner == hierFontMenuID*/
- else if( (theMenuID>0) && (theMenuID<235) ) /*range of hierarchial submenus && assume owner is hierfontMenuID*/
- {
- MenuHandle mh;
- long index;
-
- #if !defined(__powerc) && !defined(ppcinterfaces)
- mh = GetMHandle(theMenuID);
- #else
- mh = GetMenuHandle(theMenuID);
- #endif
- MoveHHi((Handle)mh);
- HLock((Handle)mh);
- BlockMove ( (**mh).menuData, str, (**mh).menuData[0]+1 ); /*the title of gxStyle menu is the family name*/
- HUnlock((Handle)mh);
- GXFindFonts(nil, gxFamilyFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, str[0], str+1, 1,1,&sfnt);
-
- index = theItem - (CountMItems( mh ) - GXCountFontInstances(sfnt)) ;
- if (index>0) /*it's an instance*/
- *instanceIndex = index;
- else
- { /*find by gxFont gxStyle name*/
- gxFont fontID;
-
- #if !defined(__powerc) && !defined(ppcinterfaces)
- GetItem(mh, theItem, str);
- #else
- GetMenuItemText(mh, theItem, str);
- #endif
- GXFindFonts(sfnt, gxStyleFontName, gxMacintoshPlatform, gxRomanScript, gxEnglishLanguage, str[0], str+1, 1,1,&fontID);
- sfnt =fontID;
- }
- }
- HiliteMenu (0);
- return(sfnt);
- }
-
- short DoHierFontMenuCommandStyle(long menuResult, short hierFontMenuID,gxStyle aStyle, long matchInfo)
- {
- short theItem = LoWord (menuResult);
- short theMenuID = HiWord (menuResult);
- gxFont sfnt;
- short success = true;
- long instanceIndex;
-
- sfnt = DoHierFontMenuCommand(menuResult, hierFontMenuID, &instanceIndex);
- if (sfnt)
- {
- if(matchInfo && ( (theMenuID == hierFontMenuID) || (theItem == 0) ))/*theItem was on the family name*/
- {
- SetMatchingStyle(sfnt, aStyle, matchInfo);
- }
- else/*no gxStyle matching*/
- {
- GXSetStyleFont(aStyle, sfnt);
- if(instanceIndex)
- {
- long howManyVariations;
- gxFontVariation *variations;
-
- howManyVariations = GXCountFontVariations(sfnt);
- variations = (gxFontVariation*)NewPtr(sizeof(gxFontVariation) * howManyVariations);
- GXGetFontInstance(sfnt, instanceIndex, variations);
- GXSetStyleFont(aStyle, sfnt);
- GXSetStyleFontVariations(aStyle, howManyVariations, variations);
- DisposePtr((Ptr)variations);
- }
- else
- GXSetStyleFontVariations(aStyle, 0, nil);
- }
- }
- else /*not our menu*/
- success = false;
-
- HiliteMenu (0);
- return(success);
- }
-
- short DoHierFontMenuCommandShape(long menuResult, short hierFontMenuID,gxShape aShape)
- {
- short theItem = LoWord (menuResult);
- short theMenuID = HiWord (menuResult);
- gxFont sfnt;
- short success = true;
- long instanceIndex;
-
- sfnt = DoHierFontMenuCommand(menuResult, hierFontMenuID, &instanceIndex);
- if (sfnt)
- {
- GXSetShapeFont(aShape, sfnt);
- if(instanceIndex)
- {
- long howManyVariations;
- gxFontVariation *variations;
-
- howManyVariations = GXCountFontVariations(sfnt);
- variations = (gxFontVariation*)NewPtr(sizeof(gxFontVariation) * howManyVariations);
- GXGetFontInstance(sfnt, instanceIndex, variations);
- GXSetShapeFont(aShape, sfnt);
- GXSetShapeFontVariations(aShape, howManyVariations, variations);
- DisposePtr((Ptr)variations);
- }
- else
- GXSetShapeFontVariations(aShape, 0, nil);
- }
- else /*not our menu*/
- success = false;
-
- HiliteMenu (0);
- return(success);
- }
-
- long FontToQD(gxFont fontID, long* styleBits)
- {
- short resID, i, count;
- OSType resType;
- Str255 resName;
- Handle sfnt;
-
- if (GXGetFont(fontID, (gxFontStorageReference*)&sfnt, nil) != gxResourceFontStorage)
- goto NOT_FOUND;
- GetResInfo(sfnt, &resID, &resType, resName);
- if (ResError())
- goto NOT_FOUND;
-
- count = CountResources('FOND');
- for (i = 1; i <= count; i++)
- { Handle fond = GetIndResource('FOND', i);
-
- if (!ResError() && fond && *fond)
- do
- { short* sp = (short*)(*fond + sizeof(FamRec));
- int entries = *sp++;
-
- for (; entries >= 0; --entries)
- { if (*sp == 0 && sp[2] == resID)
- { if (styleBits)
- *styleBits = sp[1];
- GetResInfo(fond, &resID, &resType, resName);
- return resID;
- }
- sp += 3; /* three elements in the FAT */
- }
- } while ((fond = XGetNextFOND(fond)) != 0);
- }
- NOT_FOUND:
- return 0;
- }
-
- /*************** font features *************/
-
- long GetMenuRunFeatures(MenuHandle menu, gxFont fontID, gxRunFeature feature[])
- {
- long i, featureCount, item, count;
-
- count = 0;
- item = 1;
- featureCount = GXCountFontFeatures(fontID);
- for (i = 1; i <= featureCount; i++)
- { long settingCount, j;
- gxFontFeature featureType;
- gxFontFeatureSetting* settings;
-
- GXGetFontFeature(fontID, i, nil, &settingCount, nil, &featureType);
- settings = (gxFontFeatureSetting*)NewPtr(settingCount * sizeof(gxFontFeatureSetting));
- GXGetFontFeature(fontID, i, nil, nil, settings, nil);
- for (j = 0; j < settingCount; j++)
- { short mark;
-
- GetItemMark(menu, item, &mark);
- if (mark)
- { if (feature)
- { feature[count].featureType = featureType;
- feature[count].featureSelector = settings[j].setting;
- }
- ++count;
- }
- ++item;
- }
- DisposePtr((Ptr)settings);
- if (i < featureCount)
- ++item; /* skip the underline */
- }
- return count;
- }
-
- static boolean SearchRunFeatures(long count, const gxRunFeature feature[], gxFontFeature featureType, long featureSetting)
- {
- if (count)
- { const gxRunFeature *stop = feature + count;
- do {
- if (feature->featureType == featureType && feature->featureSelector == featureSetting)
- return true;
- ++feature;
- } while (feature < stop);
- }
- return false;
- }
-
- void SetMenuRunFeatures(MenuHandle menu, gxFont fontID, long count, const gxRunFeature feature[])
- {
- long i, featureCount, item;
-
- item = 1;
- featureCount = GXCountFontFeatures(fontID);
- for (i = 1; i <= featureCount; i++)
- { long settingCount, j;
- gxFontFeature featureType;
- gxFontFeatureSetting* settings;
-
- GXGetFontFeature(fontID, i, nil, &settingCount, nil, &featureType);
- settings = (gxFontFeatureSetting*)NewPtr(settingCount * sizeof(gxFontFeatureSetting));
- GXGetFontFeature(fontID, i, nil, nil, settings, nil);
- for (j = 0; j < settingCount; j++)
- { CheckItem(menu, item, SearchRunFeatures(count, feature, featureType, settings[j].setting));
- ++item;
- }
- DisposePtr((Ptr)settings);
- if (i < featureCount)
- ++item; /* skip the underline */
- }
- }
-
- void FontFeatureMenu(MenuHandle menu, gxFont fontID)
- {
- long i, featureCount;
- gxFontName nameID;
- Str255 name;
-
- for (i = CountMItems(menu); i > 0; --i)
- DelMenuItem(menu, i);
- featureCount = GXCountFontFeatures(fontID);
- for (i = 1; i <= featureCount; i++)
- { long settingCount, j;
- gxFontFeatureSetting* settings;
-
- GXGetFontFeature(fontID, i, nil, &settingCount, nil, nil);
- settings = (gxFontFeatureSetting*)NewPtr(settingCount * sizeof(gxFontFeatureSetting));
- GXGetFontFeature(fontID, i, nil, nil, settings, nil);
- for (j = 0; j < settingCount; j++)
- { FindFontPName(fontID, settings[j].nameID, name);
- AppendMenu(menu, name);
- }
- DisposePtr((Ptr)settings);
- if (i < featureCount)
- AppendMenu(menu, "\p(-");
- }
- }
-
-